<?php

declare (strict_types=1);

namespace app\middleware;

use app\BaseController;
use thans\jwt\exception\JWTException;
use thans\jwt\exception\TokenBlacklistGracePeriodException;
use thans\jwt\exception\TokenExpiredException;
use thans\jwt\facade\JWTAuth;
use think\Request;

class Auth extends BaseController
{
	public function handle(Request $request, \Closure $next): object
	{
		$request->user_id = 0;
		try {
			$payload = JWTAuth::auth();
		} catch (TokenExpiredException $e) { // 捕获token过期
			// 尝试刷新token，会将旧token加入黑名单
			try {
				$token = JWTAuth::refresh();
				$payload = JWTAuth::auth(false);
			} catch (TokenBlacklistGracePeriodException $e) {
				$payload = JWTAuth::auth(false);
			} catch (JWTException $e) {
				// 如果捕获到此异常，即代表 refresh 也过期了，用户无法刷新令牌，需要重新登录。
				
			}
		} catch (TokenBlacklistGracePeriodException|JWTException $e) {
		
		}
		
		if (isset($payload['user_id'])) {
			$request->user_id = $payload['user_id'];
		}
		
		$response = $next($request);
		// 如果有新的token，则在响应头返回（前端判断一下响应中是否有 token，如果有就直接使用此 token 替换掉本地的 token，以此达到无痛刷新token效果）
		if (isset($token)) {
			$response = $response->header(['Authorization' => 'Bearer ' . $token]);
		}
		return $response;
	}
}
